<!DOCTYPE HTML>
<html lang="en">
    <head>
    <meta charset="UTF-8"/>


    <title>Reverse Engineering Ebpfkit Rootkit With BlackBerry&#39;s Enhanced IDA Processor Tool</title>
    
    

<script type="application/ld+json">
    {
        "@context": "https://schema.org",
        "@type": "NewsArticle",
        "mainEntityOfPage": {
            "@type": "WebPage",
            "@id": "https://blogs.blackberry.com/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool"
        },
        "headline": "Reverse Engineering Ebpfkit Rootkit With BlackBerry's Enhanced IDA Processor Tool",
        "image": [
            "/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpf-350x350-machinery.png",
            "/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpf-875x530-machinery.png"
        ],
        "datePublished": "2021-12-02T01:01:00.000-08:00",
        "author": [{
                    "@type": "Person",
                    "name": "Michael Zandi"
                }
,{
                    "@type": "Person",
                    "name": "The BlackBerry Research & Intelligence Team"
                }
],
        "publisher": {
            "@type": "Organization",
            "name": "BlackBerry",
            "logo": {
                "@type": "ImageObject",
                "url": "https://blogs.blackberry.com/content/dam/blackberry-com/Images/logos/BlackBerry_Logo_Black_150.png"
            }
        }
    }
</script>

    
    <meta name="description" content="As eBPF adoption increases, so will the need to reverse-engineer eBPF programs. To make the lives of reverse-engineers easier, BlackBerry is making an enhanced reverse-engineering tool publicly available. "/>
    
    <link rel="icon" href="/etc.clientlibs/bbcom/clientlibs/clientlib-etc-legacy/resources/bbcom-aem-project/images/favicon.ico"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    
    
    
    <link rel="canonical" href="https://blogs.blackberry.com/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool"/>
    <meta name="author" content="blogs.blackberry.com"/>
    <meta property="og:url" content="https://blogs.blackberry.com/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool"/>
    <meta property="og:title" content="Reverse Engineering Ebpfkit Rootkit With BlackBerry&#39;s Enhanced IDA Processor Tool"/>
    <meta property="og:description" content="As eBPF adoption increases, so will the need to reverse-engineer eBPF programs. To make the lives of reverse-engineers easier, BlackBerry is making an enhanced reverse-engineering tool publicly available. "/>
    <meta property="og:type" content="article"/>
    <meta property="og:image" content="https://blogs.blackberry.com/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpf-875x530-machinery.png"/>
    <meta name="twitter:card" content="summary_large_image"/>
    <meta name="twitter:site" content="@BlackBerry"/>
    <meta name="twitter:title" content="Reverse Engineering Ebpfkit Rootkit With BlackBerry&#39;s Enhanced IDA Processor Tool"/>
    <meta name="twitter:description" content="As eBPF adoption increases, so will the need to reverse-engineer eBPF programs. To make the lives of reverse-engineers easier, BlackBerry is making an enhanced reverse-engineering tool publicly available. "/>
    <meta name="twitter:image" content="https://blogs.blackberry.com/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpf-875x530-machinery.png"/>

    

    
    
<link rel="stylesheet" href="/etc.clientlibs/blogs-bbcom/clientlibs/clientlib-site.min.7737ed8dda6719e4f8a420ddbec72a71.css" type="text/css">



<!--<sly data-sly-use.clientLib="/libs/granite/sightly/templates/clientlib.html"-->
<!--     data-sly-call=""/>-->

    






<!--<script>-->
<!--    (function(g,b,d,f){(function(a,c,d){if(a){var e=b.createElement("style");e.id=c;e.innerHTML=d;a.appendChild(e)}})(b.getElementsByTagName("head")[0],"at-body-style",d);setTimeout(function(){var a=b.getElementsByTagName("head")[0];if(a){var c=b.getElementById("at-body-style");c&&a.removeChild(c)}},f)})(window,document,"body {opacity: 0 !important}",3E3);-->
<!--</script>-->

<script>
    var digitalData = {
        page: {
            pageInfo: {
                pageTitle: "Reverse Engineering Ebpfkit Rootkit With BlackBerry's Enhanced IDA Processor Tool",
                pageName: "en:2021:12:reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool",
                domain:"blogs.blackberry.com",
                hierarchy:["en","2021","12","reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool"],
                timeStamp:"2021-12-23 23:29:24",
                country:"BE"
            }
        }
    }
</script>



    <script src="//assets.adobedtm.com/cb3160b9e813/dd47d4a7a48e/launch-17c42c38011b.min.js" async></script>
<!--    <sly data-sly-include="/apps/adobe-analytics/asset-insights/prod.html"></sly>-->









<script>
    digitalData.blogPost = {
        authors:  "Michael Zandi,The BlackBerry Research & Intelligence Team",
        categories: "Research & Intelligence"
    }
</script>


<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
        new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
        j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
        'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
        })(window,document,'script','dataLayer','GTM-TXGFP23');</script>
<!-- End Google Tag Manager -->


<!-- Bizible -->
<script type="text/javascript" src="//cdn.bizible.com/scripts/bizible.js" async=""></script>
    
    
    

    
    
    
    

    
</head>
    <body class="page basicpage" data-enable-history="true">
        
        
            



            


<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-TXGFP23" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->
  
<!--
<sly data-sly-use.templatedContainer="com.day.cq.wcm.foundation.TemplatedContainer"
   data-sly-repeat.child=""
   data-sly-resource=""/>
-->

<header>
    




    
    
    
<!-- BEGIN DO NOT INDEX -->

    

<!-- skip to content: START -->
<a href='#' class='skipNav' tabindex="0">Skip Navigation</a>
<!-- skip to content: END-->
<!-- BEGIN DO NOT INDEX -->
<div class="blogs-nav-container">
  <nav class="navbar container navbar-expand-lg navbar-light blogs-navigationv1" aria-label="Main Navigation">
    
    <a class="nav-brand" href="https://blogs.blackberry.com/en">
      <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 263 58" style="enable-background:new 0 0 263 58;" xml:space="preserve">
        <style type="text/css">
          .st0 {
            fill: white;
          }
        </style>
        <g>
          <g>
            <g>
              <g>
                <path class="st0" d="M128.9,34.6c-0.2,0.5-1.5,2.9-4.6,2.9c-3.6,0-5-3-5-5.2c0-3.6,2.5-6.9,6.1-6.9c3.9,0,4.8,2.9,4.9,3.4h5.7
                                   c0.3-2.1-1.4-8.7-10.4-8.7c-6.6,0-11.9,5.3-11.9,12.3c0,5.8,3.6,10.2,10.3,10.2c8.3,0,10.6-6.5,10.9-8.1L128.9,34.6L128.9,34.6z
                                   "/>
                <path class="st0" d="M85.1,36.2c0-0.3,0.1-1,0.4-2.3S89.8,14,89.8,14h-5.4L80,34.5c-0.2,0.9-0.3,1.7-0.3,2.5
                                   c0,4.5,3.5,5.8,6.3,5.8c1,0,1.9-0.2,2.2-0.2c0.1-0.4,0.9-4.3,1-4.5c-0.1,0-0.7,0.1-1.4,0.1C85.7,38.1,85.1,37.3,85.1,36.2z"/>
                <polygon class="st0" points="161.2,20.2 153.7,20.2 144.1,28.9 147.4,13.9 142,13.9 135.8,42.3 141.2,42.3 142.7,35.4 146,32.8 
                                   150.6,42.3 156.6,42.3 150.1,29.5 				"/>
                <path class="st0" d="M55.6,33.5c0.4-2,4.3-19.6,4.3-19.6s6.6,0,10.2,0c7.4,0,9.2,4.1,9.2,6.6c0,5.5-5.2,7-5.9,7.2
                                   c0.6,0.2,4,1.5,4,5.9c0,4.7-4.4,8.7-11.1,8.7c0,0-2.4,0-3.1,0C57.6,42.3,54.5,38.4,55.6,33.5z M71.6,33.2c0-1.3-0.9-3-4.7-3h-5
                                   L60.5,37h5.6C69.7,37,71.6,35.4,71.6,33.2z M73.4,21.7c0-1.4-1.1-2.6-3.6-2.6h-5.5l-1.2,5.7h5.7C71.9,24.9,73.4,23.4,73.4,21.7z
                                   "/>
                <path class="st0" d="M158.7,33.5c0.4-2,4.3-19.6,4.3-19.6s6.6,0,10.2,0c7.4,0,9.2,4.1,9.2,6.6c0,5.5-5.2,7-5.9,7.2
                                   c0.6,0.2,4,1.5,4,5.9c0,4.7-4.4,8.7-11.1,8.7c0,0-2.4,0-3.1,0C160.7,42.3,157.7,38.4,158.7,33.5z M174.7,33.2c0-1.3-0.9-3-4.7-3
                                   h-5l-1.5,6.9h5.6C172.9,37,174.7,35.4,174.7,33.2z M176.6,21.7c0-1.4-1-2.6-3.6-2.6h-5.5l-1.2,5.7h5.7
                                   C175,24.9,176.6,23.4,176.6,21.7z"/>
                <path class="st0" d="M219.5,20.2c-5.7,0-9.6,3.4-10.9,9.7c-0.6,2.7-2.6,12.3-2.6,12.3h5.4c0,0,2-9.1,2.6-12c0.8-3.8,2.8-5,5.5-5
                                   c0.9,0,1.4,0.1,1.7,0.1c0.1-0.8,0.9-4.2,1.1-5C221.6,20.4,220.7,20.2,219.5,20.2z"/>
                <path class="st0" d="M237.7,50.7l18-30.5h-5.8l-8.3,14.4l-1.9-14.4c0,0-2.9,0-6.2,0c-7.1,0-10.8,3.2-12.1,9.4
                                   c-0.7,3.1-2.7,12.6-2.7,12.6h5.4c0,0,2-9.1,2.7-12.7c0.8-3.5,3.4-4.6,6.2-4l1.1-5.2c0.8,4.9,3.4,20.8,3.4,20.8l-5.6,9.6
                                   C231.9,50.7,237.7,50.7,237.7,50.7z"/>
                <path class="st0" d="M100.5,32.9c1.2-0.2,4.6-0.7,5.1-0.8c-0.1,0.4-0.2,1-0.3,1.4c-0.6,2.7-3.3,4.4-6.3,4.4c-1.9,0-3-1-3-2.3
                                   C95.9,34.6,96.9,33.4,100.5,32.9z M98.5,27.1c0.1-0.2,1.5-2.3,4.9-2.3c2.1,0,3.2,0.8,3.2,1.7c0,1.3-2.2,1.7-5.9,2.2
                                   c-6.4,0.9-10.5,2.9-10.5,7.5c0,3.3,2.7,6.5,7.6,6.5c4,0,6.1-2.4,6.3-2.6c0,0.6,0.1,1.5,0.2,2.2c0.4,0,4.2,0,5.5,0
                                   c-0.2-1-0.6-2.8,0.1-5.7c0.3-1.5,1.3-6,1.8-8.5c0.9-4.6-1.6-7.9-8.1-7.9c-8.4,0-10.8,6-11.2,7h6.1V27.1z"/>
                <path class="st0" d="M198.1,35.7c-0.2,0.4-1.5,2.3-4.4,2.3c-4.2,0-5.2-3.6-5.1-4.5c2.2,0,15.2,0,16.3,0c0.1-0.4,0.5-1.9,0.5-3.3
                                   c0-5.2-3.5-9.9-10.6-9.9c-6.5,0-11.7,5.4-11.7,11.9c0,6.2,3.8,10.7,10.4,10.7c8.2,0,10.4-6.4,10.6-7
                                   C202.7,35.7,198.1,35.7,198.1,35.7z M194.9,25.1c3.6,0,5,2.2,4.8,4c-2.1,0-8.2,0-10.3,0C189.7,27.9,191.4,25.1,194.9,25.1z"/>
              </g>
              <g>
                <path class="st0" d="M21.7,10.7c0-1.4-0.8-3.1-4.3-3.1c-1.4,0-5.4,0-5.4,0l-1.5,7.1c0,0,2.9,0,5.6,0
                                   C20.4,14.7,21.7,12.6,21.7,10.7z"/>
                <path class="st0" d="M36.2,10.7c0-1.4-0.8-3.1-4.3-3.1c-1.4,0-5.4,0-5.4,0L25,14.7c0,0,2.9,0,5.6,0C35,14.7,36.2,12.6,36.2,10.7
                                   z"/>
                <path class="st0" d="M19.7,21.4c0-1.4-0.8-3.1-4.3-3.1c-1.4,0-5.4,0-5.4,0l-1.5,7.1c0,0,2.9,0,5.6,0
                                   C18.5,25.4,19.7,23.3,19.7,21.4z"/>
                <path class="st0" d="M34.3,21.4c0-1.4-0.8-3.1-4.3-3.1c-1.4,0-5.4,0-5.4,0L23,25.4c0,0,2.9,0,5.6,0C33,25.4,34.3,23.3,34.3,21.4
                                   z"/>
                <path class="st0" d="M49.5,17c0-1.4-0.8-3.1-4.3-3.1c-1.4,0-5.4,0-5.4,0L38.2,21c0,0,2.9,0,5.6,0C48.2,21,49.5,19,49.5,17z"/>
                <path class="st0" d="M47.4,28.1c0-1.4-0.8-3.1-4.3-3.1c-1.4,0-5.4,0-5.4,0l-1.5,7.1c0,0,2.9,0,5.6,0
                                   C46.1,32.1,47.4,30.1,47.4,28.1z"/>
                <path class="st0" d="M32.2,32.5c0-1.4-0.8-3.1-4.3-3.1c-1.4,0-5.4,0-5.4,0L21,36.5c0,0,2.9,0,5.6,0
                                   C30.9,36.5,32.2,34.4,32.2,32.5z"/>
              </g>
            </g>
          </g>
        </g>
        <g>
          <path class="st0" d="M252.7,36c1.7,0,3.2,1.4,3.2,3.2c0,1.9-1.5,3.2-3.2,3.2c-1.8,0-3.2-1.4-3.2-3.2C249.5,37.3,251,36,252.7,36z
                        M252.7,36.5c-1.5,0-2.6,1.1-2.6,2.7c0,1.6,1.1,2.7,2.6,2.7s2.6-1.1,2.6-2.7S254.2,36.5,252.7,36.5z M252,41h-0.6v-3.7h1.4
                       c0.9,0,1.3,0.3,1.3,1.1c0,0.7-0.4,0.9-1,1l1.1,1.6h-0.6l-1-1.6H252V41z M252,38.9h0.7c0.7,0,0.9-0.2,0.9-0.6c0-0.4-0.2-0.6-0.8-0.6
                       H252V38.9z"/>
        </g>
      </svg>
      <!-- <span class="seperator">|</span>
    <span class="blogs-text">DOCS</span> -->
    </a><button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navigationv1">
      <span></span>
      <span></span>
      <span></span>
    </button>
    <div class="collapse navbar-collapse" id="navigationv1">
      <ul class="navbar-nav">
        <li class="nav-item dropdown ">
          
          
            <a class="nav-link dropdown-toggle" data-toggle="dropdown">TOPICS</a>
            
            

<div class="dropdown-menu py-1" data-two-column-layout="false">
    <!--%simple dropdown%-->

    <div class="col-md-12 px-1">
        





<ul role="menu" class="list-unstyled">
    <li role="none">
        
            <a href="/en/category/software-solutions/unified-endpoint-management#nav" role="menuitem" class="dropdown-item ">Unified Endpoint Management</a>
        
        
    </li>

    <li role="none">
        
            <a href="/en/category/software-solutions/unified-endpoint-security#nav" role="menuitem" class="dropdown-item ">Unified Endpoint Security</a>
        
        
    </li>

    <li role="none">
        
            <a href="/en/category/software-solutions/secure_comms/crisis-communications#nav" role="menuitem" class="dropdown-item ">Crisis Communications</a>
        
        
    </li>

    <li role="none">
        
            <a href="/en/category/software-solutions/secure_comms#nav" role="menuitem" class="dropdown-item ">Secure Communications</a>
        
        
    </li>

    <li role="none">
        
            <a href="/en/category/industries/automotive#nav" role="menuitem" class="dropdown-item ">Automotive</a>
        
        
    </li>

    <li role="none">
        
            <a href="/en/category/research-and-intelligence#nav" role="menuitem" class="dropdown-item ">Research &amp; Intelligence</a>
        
        
    </li>

    <li role="none">
        
            <a href="/en/category/security/zero-trust#nav" role="menuitem" class="dropdown-item ">Zero Trust</a>
        
        
    </li>

    <li role="none">
        
            <a href="/en/category/security/mobile-security/remote-working#nav" role="menuitem" class="dropdown-item ">Remote Working</a>
        
        
    </li>

    <li role="none">
        
            <a href="/en/category/software-solutions/business-continuity#nav" role="menuitem" class="dropdown-item ">Business Continuity</a>
        
        
    </li>
</ul>

    </div>



    <!--%simple dropdown%-->

    <div class="col-md-12 px-1">
        







    </div>


</div>


          
        </li>
        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle" data-toggle="dropdown">BLOGS</a>
          <div class="dropdown-menu py-1" data-two-column-layout="false">
            <!--%simple dropdown%-->
            <div class="col-md-12 px-1">

              <ul role="menu" class="list-unstyled">
                <li role="none">
                  <a href="https://blogs.blackberry.com#nav" rel="noopener" role="menuitem" class="dropdown-item ">BlackBerry ThreatVector Blog </a>
                </li>
                
                <li role="none">
                  <a href="https://devblog.blackberry.com#nav" rel="noopener" role="menuitem" class="dropdown-item " target="_blank">Developer Blog</a>
                </li>
                <li role="none">
                  <a href="https://helpblog.blackberry.com#nav" rel="noopener" role="menuitem" class="dropdown-item " target="_blank">Help Blog</a>
                </li>
              </ul>
            </div>

          </div>
        </li>
        <li class="nav-item bbcom">
          <a class="nav-link" target="_blank" href="https://www.blackberry.com#nav">BLACKBERRY.COM</a>
        </li>
      </ul>
      <ul class="navbar-nav ml-auto">
        <li class="nav-item active">
          
          <a class="nav-link open-search-btn" role="button">
            <svg aria-hidden="true" data-prefix="fa" data-icon="search" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" data-fa-i2svg="">
              <path fill="currentColor" d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z">
              </path>
            </svg>
          </a>
          <div id="searchOverlay" class="search-overlay">
            <span class="close-search-btn" title="Close Search">×</span>
            <div class="overlay-content">
              <form id="search-form">
                <input id="search-form--input" description="Search" data-search-url="https://blogs.blackberry.com/en/search" type="text" placeholder="Search" name="search"/>
                <!-- no font awesome -->
                <button type="submit">
                  <svg aria-hidden="true" data-prefix="fa" data-icon="search" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" data-fa-i2svg="">
                    <path fill="currentColor" d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z">
                    </path>
                  </svg>
                </button>
              </form>
            </div>
          </div>
        </li>
        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle contact-us">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
              <path fill="currentColor" d="M402.3 344.9l32-32c5-5 13.7-1.5 13.7 5.7V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h273.5c7.1 0 10.7 8.6 5.7 13.7l-32 32c-1.5 1.5-3.5 2.3-5.7 2.3H48v352h352V350.5c0-2.1.8-4.1 2.3-5.6zm156.6-201.8L296.3 405.7l-90.4 10c-26.2 2.9-48.5-19.2-45.6-45.6l10-90.4L432.9 17.1c22.9-22.9 59.9-22.9 82.7 0l43.2 43.2c22.9 22.9 22.9 60 .1 82.8zM460.1 174L402 115.9 216.2 301.8l-7.3 65.3 65.3-7.3L460.1 174zm64.8-79.7l-43.2-43.2c-4.1-4.1-10.8-4.1-14.8 0L436 82l58.1 58.1 30.9-30.9c4-4.2 4-10.8-.1-14.9z">
              </path>
            </svg>
          </a>
          <div class="dropdown-menu py-1 dropdown-menu-right" data-two-column-layout="false">
            <!--%simple dropdown%-->
            <div class="col-md-12 px-1">

              <ul role="menu" class="list-unstyled">
                <li role="none">
                  <a href="https://www.blackberry.com/us/en/forms/enterprise/register-for-updates#nav" target="_blank" rel="noopener" role="menuitem" class="dropdown-item ">Register for Updates</a>
                </li>
                <li role="none">
                  <a href="https://www.blackberry.com/us/en/forms/enterprise/contact-us#nav" target="_blank" rel="noopener" role="menuitem" class="dropdown-item">Contact Sales</a>
                </li>
                
                <li role="none">
                  <a href="https://www.blackberry.com/us/en/support/contact#nav" rel="noopener" target="_blank" role="menuitem" class="dropdown-item">Contact Us</a>
                </li>
              </ul>
            </div>

          </div>
        </li>
      </ul>
    </div>
  </nav>
</div>
<!-- END DO NOT INDEX -->



<!-- END DO NOT INDEX -->

    
    
    <div class="hero">

      <div class="jumbotron mastheadDefault">
        <div class="hero-container narrower" style="background-image: url( \2f content\2f dam\2f blackberry-com\2fImages\2fsupport\2f bgs\2f bnr-blue-gradient-crop.jpg)">
          
          <div class="mask  "></div>

          <div class="container headings  l-align">
            <div class="col-lg-12">
          		




    
    
    <div class="blog-name-title">

  <div class="cmp-title ">
  
  
   <!-- <span class="highlighted-text-title blogs">INSIDE</span>
   <span class="normal-text-title">BlackBerry Blog</span> -->
   <span class="normal-text-title">BlackBerry ThreatVector Blog</span>
  
  
  
</div>
</div>



          	</div>
          </div>
      </div>
    </div>
</div>



</header><main>
    




    
    
    <div class="section">
  <section class="section     ">
    
    <div class="container">
        




    
    
    
<ol class="breadcrumb">
    <li class="breadcrumb-item ">
        <a href="/en.html">BlackBerry ThreatVector Blog</a>
    </li>

    <li class="breadcrumb-item active">
        Reverse Engineering Ebpfkit Rootkit With BlackBerry&#39;s Enhanced IDA Processor Tool
    </li>
</ol>

    


      
    </div>
  </section>
    

</div>


    
    
    <div class="blogsection">
    <section class="section     ">
      
      <div class="container sectionPadding py-0">
           
      <div class="col-md-9 col-lg-9 col-sm-12">
          




    
    
    <div class="cmp cmp-title blog-title row">
  

<div class="col-md-12 col-lg-12 col-sm-12">
<h1>Reverse Engineering Ebpfkit Rootkit With BlackBerry&#39;s Enhanced IDA Processor Tool</h1>
</div>



    
</div>


    
    
    <div class="categorydateauthor"><!--Pulling author bio from author page-->
<div class="categorydateauthor">
<span><a title="RESEARCH &amp; INTELLIGENCE" href="/en/category/research-and-intelligence">RESEARCH &amp; INTELLIGENCE</a> / </span><span class='publish-date'></span>12.02.21 / </span>

    <span class="author"><a href="/en/author/the-blackberry-research-and-intelligence-team">The BlackBerry Research &amp; Intelligence Team</a>, <a href="/en/author/michael-zandi">Michael Zandi</a></span>

</div></div>


    
    
    <div class="socialsharing">

<div class='socialSharing row'>
  <ul class='socialSharing-icons'>
    <li>
        <a href='https://twitter.com/intent/tweet?url=https://blogs.blackberry.com/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool&text=Reverse%20Engineering%20Ebpfkit%20Rootkit%20With%20BlackBerry%27s%20Enhanced%20IDA%20Processor%20Tool&via=BlackBerry' title="Share on Twitter" target="_blank" class="twitter-share">
        <span class='sr-only sr-only-focusable'>Share on Twitter</span>
        <span class='svgIcon-socialSharing svgIcon-socialSharing--tw' aria-hidden='true'>
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
        </span>
      </a>
    </li>    
    <li>
      <a href='https://www.facebook.com/sharer/sharer.php?u=https://blogs.blackberry.com/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool' title="Share on FaceBook" target="_blank" class="facebook-share">
        <span class='sr-only sr-only-focusable'>Share on Facebook</span>
        <span class='svgIcon-socialSharing svgIcon-socialSharing--fb' aria-hidden='true'>
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 264 512"><path d="M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"/></svg>
        </span>
      </a>
    </li>
    <li>
      <a href="https://www.linkedin.com/shareArticle?mini=true&url=https://blogs.blackberry.com/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool&title=Reverse%20Engineering%20Ebpfkit%20Rootkit%20With%20BlackBerry%27s%20Enhanced%20IDA%20Processor%20Tool&summary=&source=blogs.blackberry.com" title="Share on LinkedIn" target="_blank" class="linkedin-share">
        <span class='sr-only sr-only-focusable'>Share on Linked In</span>
        <span class='svgIcon-socialSharing svgIcon-socialSharing--li' aria-hidden='true'>
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448.1 512"><path d="M100.3 448H7.4V148.9h92.9V448zM53.8 108.1C24.1 108.1 0 83.5 0 53.8S24.1 0 53.8 0s53.8 24.1 53.8 53.8-24.1 54.3-53.8 54.3zM448 448h-92.7V302.4c0-34.7-.7-79.2-48.3-79.2-48.3 0-55.7 37.7-55.7 76.7V448h-92.8V148.9h89.1v40.8h1.3c12.4-23.5 42.7-48.3 87.9-48.3 94 0 111.3 61.9 111.3 142.3V448h-.1z"/></svg>
        </span>
      </a>
    </li>
    <li>
      <a href="mailto:?subject=Reverse%20Engineering%20Ebpfkit%20Rootkit%20With%20BlackBerry%27s%20Enhanced%20IDA%20Processor%20Tool&body=https://blogs.blackberry.com/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool" title="Email" class="email-share">
        <span class='sr-only sr-only-focusable'>Email</span>
        <span class='svgIcon-socialSharing svgIcon-socialSharing--li' aria-hidden='true'>
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z"/></svg>
        </span>
      </a>
    </li>    
  </ul>
</div>
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_1245810710.coreimg{.width}.png/1638465132532/ebpf-875x530-machinery.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpf-875x530-machinery.png" data-asset-id="49c2a5f0-b5c4-47c8-b489-f5b240a66348" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpf-875x530-machinery.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p>Any new technology can be used by malware or for otherwise malicious purposes, and eBPF is no exception. The researchers who introduced the proof-of-concept ebpfkit rootkit in 2021 demonstrated that this functionality can be used for malicious purposes. As its threat potential grows, the security community must develop new tools to respond.</p>
<p>eBPF is revolutionizing how Linux® applications collect data from - and within certain limitations extend - the Linux kernel. This kind of visibility and functionality used to require a kernel module, which increased the risk of “kernel panics” and deadlocks, but is now safe enough to routinely implement on live production systems. As one would expect, this has led to many new eBPF-based projects, especially in the area of networking and security functionality.</p>
<p>eBPF has also attracted growing attention for use in security roles such as with <a href="https://lwn.net/Articles/798157/" target="_blank">Linux KRSI</a>, and it is used internally at Fortune 500 companies such as <a href="https://netflixtechblog.com/search?q=eBPF" target="_blank">Netflix</a>. The low overhead, safety, and visibility will make eBPF an important technology for anyone who needs to get the most out of their Linux machines. &nbsp;</p>
<p>As eBPF adoption increases, so will the need to reverse-engineer eBPF programs, but current tools are insufficient for dealing with reverse-engineering real world eBPF programs. To close this gap and make the lives of reverse-engineers easier, BlackBerry is making an enhanced reverse-engineering tool publicly available.</p>
<p>In this blog, we introduce an <a href="https://github.com/cylance/eBPF_processor" target="_blank">IDA processor module for the eBPF instruction set,</a> along with helper scripts necessary for reasonable reversing. This project is currently in an alpha state, as a minimum viable tool. Much progress can still be made on it, but it’s a great step forward compared with current options we’re aware of.</p>
<h3><b>Introducing the BlackBerry eBPF Reverse Engineering Tool</b></h3>
<p>First up, the processor module is installed by placing it in <a href="https://hex-rays.com/ida-pro/" target="_blank">IDA</a>'s&nbsp;“procs”&nbsp;folder, while the scripts can reside anywhere.</p>
<p>The&nbsp;“annotate_ebpf_helpers.py”&nbsp;script requires no dependencies, but the&nbsp;“annotate_relocations.py”&nbsp;script requires both that you have the&nbsp;<a href="https://pypi.org/project/pyelftools/" target="_blank">pyelftools package</a> installed and the original eBPF ELF (<a href="https://en.wikipedia.org/wiki/Executable_and_Linkable_Format" target="_blank">Executable and Linkable Format</a>) file that you are reversing.</p>
<p>Once IDA loads and analyzes a file, the original file is no longer necessary and may be discarded by the user, but for now we need to keep it. By putting this all together, we can use IDA to analyze eBPF programs, disassemble instructions, and annotate some necessary information such as helper function calls and map references.</p>
<p>As an example of how to reverse engineer a complex, real-world eBPF-based application, we'll walk you through disassembling and analyzing <a href="https://github.com/Gui774ume/ebpfkit" target="_blank">ebpfkit</a>.&nbsp;Ebpfkit is a proof-of-concept rootkit that uses eBPF for much of its functionality; it debuted at both Black Hat USA 2021 and Defcon 29. This application utilizes a complex collection of eBPF programs that cooperate with each other, including a userland component, to serve as a rootkit.</p>
<p>But before we dive into that, we need to cover eBPF and modern eBPF toolchains.</p>
<h3><b>What is eBPF?</b></h3>
<p>In short, eBPF stands for Extended Berkeley Packet Filter. Berkeley Packet Filter (BPF) was first created in the early 90s as a way to perform packet filtering in the kernel. Several years later, eBPF was introduced as a feature of the Linux kernel that was designed to enable safe and powerful tracing for performance and debugging. This is accomplished by defining a restricted virtual machine (VM) that resides in the Linux kernel, which can run eBPF programs loaded by privileged users.</p>
<p>These programs are attached to various points in the kernel using features like tracepoints, kprobes, and kretprobes. For example, a user-defined program can run each time a particular kernel function is called. This is incredibly useful for profiling a server, but it isn't anything a custom kernel module couldn't do. This is where the restrictions and safety come in.</p>
<p>By restricting what eBPF programs are allowed to do, and by passing all eBPF programs through a verifier as part of the loading process, eBPF programs can be considered safe. This means that they won't deadlock or “kernel panic” your system, and they are suitable for use on in-production servers, which is where you will most likely need to be profiling tricky performance issues and debugging rare bugs.</p>
<p>eBPF programs are held to some important restrictions that limit their functionality so that they can't crash or hang a system. Some of these restrictions are as follows:</p>
<ul>
<li>Programs are validated to run to completion.</li>
<li>No unbounded loops are allowed (if loops are allowed at all, which depends on kernel version).</li>
<li>Uninitialized variables cannot be used, and memory accesses must be within bounds.</li>
<li>Programs are limited in size.</li>
<li>The verifier must be able to verify all execution paths in the eBPF program.<br>
</li>
</ul>
<h3><b>Building and Loading eBPF Programs: Clang/LLVM + libbpf</b></h3>
<p>eBPF programs are sent to the kernel for loading via the bpf syscall, which expects an array of eBPF instructions. Programmers can write these programs by hand, one instruction at a time, but this is too unwieldy and time-consuming for most users.</p>
<p>Directly using the bpf syscall also becomes unwieldy, in part because of the need to handle differences in the eBPF subsystem between kernel versions, but also due to the low-level nature of directly using syscalls. Instead, Clang/LLVM has added support for writing eBPF programs in C, and the Linux kernel provides the libbpf library to make using the eBPF subsystem easier.</p>
<p>Modern toolchains for eBPF programs, and the toolchain our new tool is designed against, involve writing eBPF programs in C. Recent Clang/LLVM versions are used to produce eBPF bytecode with the various transformations that the verifier would require, producing an ELF relocatable object file.</p>
<p>Without reading commit messages and dev mailing lists, my interpretation of the situation is that the ELF format was just a natural fit for bundling eBPF programs with necessary meta-information, because it required minimal change to support within existing tools.</p>
<p>These ELFs are interpreted by libbpf to handle a few different necessary tasks such as: figuring out what maps to create as well as how to load and attach the programs; making any changes necessary for the programs to work with the running kernel's types; and anything else that needs to be done.</p>
<p>Overall, the whole development process is much less of a headache for developers than just a few years ago. You &quot;just&quot; have to build the eBPF objects separately, include the files in your userland component, and use libbpf to load and interface with them.<br>
</p>
<h3><b>How Do We Reverse-Engineer eBPF Programs?</b></h3>
<p>This introduces an interesting problem. If we have eBPF programs loaded on our system, or which are provided to us in binary format, how do we determine what they do? As eBPF projects adopt <a href="https://github.com/libbpf/libbpf" target="_blank">libbpf</a> and move towards <a href="https://www.brendangregg.com/blog/2020-11-04/bpf-co-re-btf-libbpf.html" target="_blank">BTF and CO-RE</a>, we can't expect source code to be available for eBPF programs. We need a way to reverse them.</p>
<p>Until now, this hasn't been possible with industry-standard tools like IDA.&nbsp;LLVM-objdump, the LLVM project’s utility for dumping info from object files which supports disassembling eBPF,&nbsp;is very nice and helpful but too simple for bigger reversing jobs: It can disassemble eBPF but it doesn’t produce a call graph, allow for commenting, or provide features that users of IDA expect. Likewise,&nbsp;bpftool&nbsp;is very useful for examining the state of eBPF programs/maps/etc. on a running system, but it isn't designed for reversing these programs.</p>
<h3><b>Reversing a Proof-of-Concept eBPF Rootkit: ebpfkit</b></h3>
<p>We'll use ebpfkit to demonstrate how this processor module and scripts enable us to reverse engineer eBPF programs. ebpfkit builds to a <a href="https://blogs.blackberry.com/en/2021/07/old-dogs-new-tricks-attackers-adopt-exotic-programming-languages" target="_blank">Go binary</a>, which loads and interfaces with the eBPF programs that implement the in-kernel portion of the rootkit.</p>
<p>Skipping the step of extracting the eBPF ELF objects from the Go binary, we can directly use the eBPF ELF objects produced during the build; they're in the ebpf/bin/&nbsp;directory of the project after building. We'd eventually get them anyway, from static or even dynamic analysis, so this isn't an unreasonable thing to fast forward to.</p>
<p>The&nbsp;bootstrap.o&nbsp;file is smaller than&nbsp;main.o, so let's start there. We open it in IDA, using the standard ELF loader, and select our eBPF processor. Then we click &quot;Yes&quot; on some of the extra confirmation/warning dialogs that come up.</p>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_1315226195.coreimg{.width}.png/1638465132548/ebpfkit-fig01.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig01.png" data-asset-id="438f151e-d975-40ee-bd7b-4a6d11fc7db2" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig01.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p><i>Figure 1 – Processor selection dialogue in IDA</i></p>
<p>After letting the auto-analysis finish, even though IDA doesn't yet know how to fully analyze these files like typical PE or ELF objects, we immediately have some useful information. Just by looking at function names, and the sections they reside in, we can learn where each of these programs are attached, and how. We get this information because of the various conventions libbpf expects eBPF ELF files to conform to for opening and loading them.</p>
<p>For example, the image below shows us that the&nbsp;_vfs_open&nbsp;function in the&nbsp;krpobe_vfs_open&nbsp;section is very likely to be attached to the&nbsp;vfs_open&nbsp;function via kprobe, which we can find in the Linux kernel source&nbsp;<a href="https://elixir.bootlin.com/linux/v5.14.1/source/fs/open.c#L946" target="_blank">here, in fs/open.c</a>. This looks like a good function to intercept and observe so we can modify all file open operations, which nearly any rootkit would need to do to at least hide itself. But this is just the bootstrap component, not the main rootkit module.</p>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_1019887578.coreimg{.width}.png/1638465132564/ebpfkit-fig02.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig02.png" data-asset-id="13f98a8b-575d-43af-8dbc-002a409aefa4" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig02.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p><i>Figure 2 – _vfs_open eBPF program in IDA</i></p>
<h3><b>eBPF Helpers</b></h3>
<p>Reading the disassembly, we quickly notice that the&nbsp;call&nbsp;instructions aren't very helpful. In eBPF, most of the heavy lifting is done with helper functions. These are kernel functions that our eBPF programs are allowed to call. This is one way that the safety conditions of a verified eBPF program are maintained.</p>
<p>Anything that may require unbounded loops or more involved memory access can be offloaded to a kernel function. This function can be more strictly checked for correctness and safety by kernel developers, rather than allowing arbitrary eBPF programs greater access and power than they need.</p>
<p>This all means that, at this stage, calling helpers with the&nbsp;call&nbsp;instruction is done by calling an integer representing the ID of the helper function. This is defined&nbsp;<a href="https://elixir.bootlin.com/linux/v5.14.1/source/include/uapi/linux/bpf.h#L4784" target="_blank">in this macro responsible for populating the bpf_func_id enum</a>. As we can see, reading the disassembly like this isn't helpful.<br>
</p>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_739321376.coreimg{.width}.png/1638465132580/ebpfkit-fig03.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig03.png" data-asset-id="f6a25d63-edf4-4642-8fc2-c9eb6134b8da" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig03.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p><i>Figure 3 – Unannotated call instruction</i></p>
<p>Here's where the first of our annotation scripts come in. Thankfully, the Linux kernel developers have some good tooling set up for generating eBPF helper documentation, which we can reuse to annotate helper calls. This way, we can have the full signature of the helper as a comment alongside each call, so we know what the helper function is, what parameters and types it is expecting, and what it returns. Simply go to &quot;File &gt; Script file...&quot; (Alt+F7) and select our&nbsp;annotate_ebpf_helpers.py&nbsp;script.</p>
<p>For every function in the binary, this script iterates over all its instructions, annotating each call instruction we see. It then dumps some helpful output to IDA's output window along the way.<br>
</p>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_1951201972.coreimg{.width}.png/1638465132596/ebpfkit-fig04.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig04.png" data-asset-id="56f848de-e75f-43bd-9afd-6c0e31b244e2" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig04.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p><i>Figure 4 – Annotated call instruction</i></p>
<p>Now that we can see what helpers these call instructions are calling, we can determine what these parameters and local variables are. Much better!</p>
<p>As we dig in, the first thing we notice is that the&nbsp;tgid/pid&nbsp;combination of the calling thread is saved to a local variable. This program then saves the&nbsp;tgid&nbsp;to&nbsp;r0, and it loads&nbsp;r1&nbsp;with a 64-bit 0. We then compare our own tgid with r1, and conditionally jump if they're equal.</p>
<p>In case you aren't familiar (I wasn't a few months ago!), there's a difference here in terminology between userland and “kernelland.” In Linux, every process has a process id (pid), and every thread has a thread id. Each thread of a process has its own thread id, but it shares the same pid as other threads in the process. But the way this is done internally uses slightly different names. Each thread has a&nbsp;pid&nbsp;but is in a thread group with other threads, referred to by&nbsp;tgid. So, threads in the same process have different&nbsp;pids&nbsp;but the same&nbsp;tgid.</p>
<p>Going from userland terminology to kernel terminology, what userspace sees as a pid&nbsp;is a tgid in the kernel, and what userspace sees as a thread id is a pid in the kernel.</p>
<h3><b>Relocations for Globals and eBPF Maps</b></h3>
<p>eBPF maps are key/value stores that are the primary tool for persisting variables beyond any particular invocation of an eBPF program. They're used for communication between eBPF programs, handling data outside the stack, and even limited communication with userspace. Maps are heavily used in all but the simplest eBPF programs, but they aren't allocated until runtime.</p>
<p>How this works is that a map is created, the eBPF programs are fixed up with the map's value, then the program is loaded. We can't know how to reference any particular map until we're loading our eBPF programs.</p>
<p>Similarly, there are a lot of situations where an eBPF program will need to reference a value that can't be known until&nbsp;the eBPF program is being loaded. For convenience, we want to treat this value as a static or global variable in our eBPF program's C source. These are both handled using relocations, where a placeholder value is used in the binary when it is built, and it’s fixed later at load time. Let's examine how this is done.</p>
<h3><b>Testing PID/TGID for &quot;Secret&quot; Value</b></h3>
<p>This comparison of the caller’s tgid against a hardcoded tgid looks like a commonly used conditional to change how we handle a system call based on what program is calling it. This often occurs because our rootkit's userland component is the one calling it and shouldn't be interfered with. But how could this be if we only ever compare against a hardcoded&nbsp;tgid&nbsp;of&nbsp;0?</p>
<p>We can only know what&nbsp;tgid&nbsp;we want to have special handling for at runtime, long after this object is built.</p>
<p>It turns out that this problem is something that has existed for decades. It has also been solved for decades by binary object formats that support relocations and have loaders to fix them up. In fact, libbpf supports exactly that, and we can use this information to aid our reversing with the helper annotation script.</p>
<p>Let’s revisit &quot;File &gt; Script file...&quot; (Alt+F7), but this time we’ll select&nbsp;annotate_relocations.py. This will use&nbsp;pyelftools&nbsp;to process the section headers of the eBPF ELF object, find relocations of maps and globals, and annotate them.</p>
<p>If the global or map has a definition that resides in the ELF file, we’ll add a data xref in IDA so we can link together other references to this data, and we can more easily link related programs to each other in informative ways. In cases where the relocated symbol is treated as an extern, we just comment it, and leave proper handling of the cross-references to a later version of these tools.</p>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_1543273753.coreimg{.width}.png/1638465132612/ebpfkit-fig05.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig05.png" data-asset-id="38be6573-d9f7-43bb-87ae-c4ce09c71aeb" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig05.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p><i>Figure 5 – Annotated global variable</i></p>
<p>Nice! With the annotated global variable, this makes much more sense.</p>
<p>At load time, ebpfkit must overwrite this value with the pid of its userland component. The way that this object is built,&nbsp;ebpfkit_pid&nbsp;is treated as an extern; a value that resides outside the object. We don't get nice cross-references to other locations that use it, but they'll at least be commented.</p>
<p>Now let's look at the rest of this&nbsp;_vfs_open&nbsp;eBPF program. This conditional is likely to make sure that any shenanigans that are done for the open syscall don't prevent the rootkit's userland component from functioning. In fact, this is precisely what happens. The true branch of that instruction has us return immediately, skipping all the other logic in this program.</p>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_98001995.coreimg{.width}.png/1638465132628/ebpfkit-fig05b.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig05b.png" data-asset-id="4afd463c-20ad-4819-8bd8-a220c8f90f6a" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig05b.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    Let's get a nicer look at this in graph view.<br>
&nbsp;
    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_2123644317.coreimg{.width}.png/1638465132644/ebpfkit-fig06.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig06.png" data-asset-id="f688d00c-a0ed-4df1-bedd-4bc898cb6aa0" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig06.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p><i>Figure 6 – IDA Graph view error message, graph too big</i></p>
<p>Unfortunately, it’s too large. One of the conditions the eBPF verifier imposes on eBPF programs is that they must end in finite time. This has actually been modified in certain ways, as eBPF has evolved. But for a long time, what this meant was that no backward edges were allowed in eBPF programs. But how would you do loops then?</p>
<p>You unrolled loops, and just accepted the massive bloat in program size (if it still loaded). This means that any eBPF programs that had to do string comparisons, or walk linked lists or similar data structures, had to unroll these loops. And you sometimes still had to do clever tricks to fit within program size constraints.</p>
<p>Increasing the limit to 5000 in &quot;Options &gt; General,&quot; then the &quot;Graph&quot; tab and the &quot;Max number of nodes&quot; field, let us use graph view. For reference, this is what an unrolled loop looks like: a conditional chain of basic blocks with repeated/identical code. Zooming out even more, we see a pattern that likely contains the code within the loop's block, and apparently contains other loops within itself.</p>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_1673116616.coreimg{.width}.png/1638465132660/ebpfkit-fig07-and-08.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig07-and-08.png" data-asset-id="da5afc3d-cc4f-4f7c-8956-81e5054b5dcb" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig07-and-08.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p><i>Figures 7 and 8 – _vfs_open eBPF program in graph view, showing unrolled loop pattern</i></p>
<h3><b>Inlined Functions</b></h3>
<p>Zooming in a bit more, we see that the most repeated blocks are performing XORs and multiplications with what look like hardcoded magic values, as they walk down a buffer on the stack, with an exit condition if a zero byte is reached. This sounds a lot like computing a hash on a string. In fact, if we search for some of the bytes involved in one of the magic values, we find many other bits of code that seem to have an identical form.<br>
</p>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_915712892.coreimg{.width}.png/1638465132676/ebpfkit-fig09.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig09.png" data-asset-id="e62f172d-54ef-4534-a6b7-cfe1bc49d431" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig09.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <i>Figure 9 – Hash algorithm update step, used for string comparison<br>
&nbsp;</i>
    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_707581225.coreimg{.width}.png/1638465132692/ebpfkit-fig10.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig10.png" data-asset-id="fdd10678-8826-4a96-8d4d-f0091acdf744" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig10.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p><i>Figure 10 – Other possible inlined hash calculations</i></p>
<p>Examining the matching functions, it appears that some of these are inlined into our eBPF programs. This is another result of eBPF restrictions. We can't call our other functions from our eBPF program like we can with most other languages. The closest we can do is tail calls to other loaded eBPF programs, which is designed more for a situation where you want to dispatch to particular eBPF handlers.</p>
<p>But this isn't useful&nbsp;if we want our own utility functions to do common tasks that we might want to call from the middle of eBPF programs, or to call multiple times. So, any of our own utility functions that we write to be used in multiple eBPF programs must be inlined, which would bloat our eBPF programs even more. It seems almost like a fluke of the tool chain and build process that these inlined functions are included in the binary on their own, as well as inlined into eBPF programs.</p>
<p>If we spend some more time determining what portions of&nbsp;_vfs_open&nbsp;correspond to which inlined utility functions (like get_comm_hash or fa_path_attr_matches) we can better break down what this unrolled loop of inlined functions is doing. Looking at which helpers are called, and which maps are referenced would help. A script looking for these repeated chunks of instructions may be helpful as well, but I don't have one. This part doesn't sound fun or as relevant to eBPF itself, so I won't go through it.</p>
<h3><b>Variable Persistence and Modifying Return Values</b></h3>
<p>Here's a slightly nicer example of an eBPF program in the ebpfkit rootkit to reverse, with less going on with unrolled loops and inlined functions. Behold&nbsp;kretprobe___64_sys_openat, in the section&nbsp;kretprobe___x64_sys_openat&nbsp;:<br>
</p>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_2045576833.coreimg{.width}.png/1638465132708/ebpfkit-fig11.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig11.png" data-asset-id="9e7c3e00-9bc3-4360-b2cd-ac459adf082e" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig11.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p><i>Figure 11 – kretprobe___64_sys_openat eBPF program</i></p>
<p>We see that if we don't have an entry in the&nbsp;fa_fd_actions&nbsp;map corresponding to this tgid/pid, we skip all processing and simply return. Because we attach eBPF programs to tracepoints/kprobes/kretprobes, they behave more like small programs run on events, rather than like typical userland programs that run for extended periods and which are essentially independent of external input.</p>
<p>One of the consequences of this is that if we want to persist variables between eBPF programs, like a paired kprobe/kretprobe on the same function, we essentially need to use maps. If this rootkit wants to manipulate syscall parameters/results for only certain processes (e.g., not the rootkit's own userland component) then it needs to store some sort of meta-information telling kretprobes whether to do something malicious.</p>
<p>Thanks to the relocation annotating script, we can look up cross-references to this&nbsp;fa_fd_actions&nbsp;map to see where else it's used. It turns out that one of the locations it’s referenced is at the end of the&nbsp;_vfs_open&nbsp;function we were looking at earlier. This confirms my suspicion that this map is used, at least in part, to indicate to the kretprobe whether to interfere when it is invoked.<br>
</p>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_1683060755.coreimg{.width}.png/1638465132724/ebpfkit-fig12.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig12.png" data-asset-id="ea6a4492-fc05-46ea-b312-27ddc609cfff" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig12.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <i>Figure 12 – Cross-references to fa_fd_actions map<br>
&nbsp;</i>
    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_2131076395.coreimg{.width}.png/1638465132739/ebpfkit-fig13.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig13.png" data-asset-id="fda25545-8af1-4284-ab04-80069f772aac" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig13.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p><i>Figure 13 – fa_fd_actions map update in _vfs_open eBPF program</i></p>
<p>At a high level, the fd_fd_actions map is used to optionally modify the return value of this syscall. Let’s break down why in more detail.</p>
<p>A context parameter is passed to each eBPF program when it is invoked. This would contain register contents and thus the parameters for the function we are attached to. The sys_openat kretprobe examines the context passed to the eBPF program, which was saved to&nbsp;r6&nbsp;in the beginning of this program. It then reads data from the&nbsp;fa_fd_actions&nbsp;element that was saved for this kretprobe, and uses this to update a corresponding element in the&nbsp;fa_fd_attrs&nbsp;map. We then test a value in our fa_fd_actions entry – specifically the 0x4&nbsp;bit now stored in&nbsp;[r10 - 0x58] – to determine whether to call&nbsp;bpf_override_return. In certain cases, bpf_override_return allows us to override the return value of the function we're attached to, supplying our own return value. Just the sort of thing a rootkit might want to do.<br>
<br>
More reversing needs to be done. But just from this, we can say that it's highly likely these eBPF programs attached to their own kprobe and kretprobe cooperate to manipulate expected syscall behavior for programs that aren't the rootkit's userland component.</p>
<h3><b>Inlined Strings</b></h3>
<p>There's another quirk I've noticed in eBPF ELF binaries that I would like to cover, but this&nbsp;bootstrap.o&nbsp;object file doesn't have an example of it. For this, we'll turn to&nbsp;main.o&nbsp;of ebpfkit. Following the same steps as above, we open it with the standard ELF loader, selecting our eBPF processor module, and run our&nbsp;annotate_ebpf_helpers.py&nbsp;and&nbsp;annotate_relocations.py&nbsp;scripts.</p>
<p>Now we look at the strings IDA knows about, by going to &quot;View &gt; Open Subviews &gt; Strings&quot; (Shift + F12).<br>
</p>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_1735962541.coreimg{.width}.png/1638465132755/ebpfkit-fig14.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig14.png" data-asset-id="348148f1-0ffc-4735-8390-6804ee5078da" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig14.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p><i>Figure 14 – Strings in main.o detected by IDA</i></p>
<p>Nice! We should be able to use these strings to help reverse eBPF programs by learning what they're up to.</p>
<p>Let's focus on the SYN string. Going to its definition in the&nbsp;.rodata.str1.16&nbsp;section, we find that there are unfortunately no known cross-references to it. The standard IDA loader doesn't know how to handle the architecture of this ELF file, and our relocation annotating script either missed this case, or there was no relocation for this data.</p>
<p>Let's go to &quot;Search &gt; Sequence of bytes...&quot; (Alt + B) while viewing disassembly to search for the hex byte sequence&nbsp;53 59 4e, which corresponds to &quot;SYN&quot; in ASCII encoding, and backwards.<br>
</p>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_338060931.coreimg{.width}.png/1638465132771/ebpfkit-fig15.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig15.png" data-asset-id="51ae1d15-6f3c-49fe-a2a5-b3fc39d48ac4" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig15.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <i>Figure 15 – Searching for bytes corresponding to “SYN” in ASCII encoding<br>
&nbsp;</i>
    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_1966971638.coreimg{.width}.png/1638465132787/ebpfkit-fig16.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig16.png" data-asset-id="099f28bf-b9ee-4228-8608-802b25489335" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig16.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <i>Figure 16 – Results searching for “SYN” ASCII byte sequence<br>
&nbsp;</i>
    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_1416991856.coreimg{.width}.png/1638465132802/ebpfkit-fig17.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig17.png" data-asset-id="0ef5daad-ff4e-4d11-be50-77d790ed24d2" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig17.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p><i>Figure 17 – Only other existing match for “SYN” ASCII byte sequence, in the immediate of an instruction</i></p>
<p>Interesting! We have only one other match in the whole binary – in the&nbsp;xdp_ingress_syn_loop&nbsp;section – with a function of the same name. Looking at the matching bytes, they're in a 64-bit load immediate instruction that is used to build a string on the stack for a&nbsp;bpf_trace_printk&nbsp;call. Using the &quot;R&quot; hotkey to interpret these immediates as strings makes this clearer. This is currently a bit finicky, and it doesn't always like to interpret the last portion as a string.<br>
</p>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_1173062761.coreimg{.width}.png/1638465132819/ebpfkit-fig18.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig18.png" data-asset-id="187c121a-847a-42f1-b92c-e149f4da8f51" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig18.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p><i>Figure 18 – Interpreting instruction immediates as strings in IDA for improved readability</i></p>
<p>Just as a sanity check, let's see what&nbsp;llvm-objdump&nbsp;thinks of relocations for this section:<br>
&nbsp;</p>
<p>$ llvm-objdump --reloc ../ebpfkit/ebpf/bin/main.o<br>
</p>
<p>...<br>
<br>
</p>
<p>RELOCATION RECORDS FOR [xdp/ingress/syn_loop]:<br>
</p>
<p>00000000000000d8 R_BPF_64_64 tcp_ip_scan_key<br>
</p>
<p>00000000000000f8 R_BPF_64_64 network_scans<br>
</p>
<p>0000000000000278 R_BPF_64_64 network_flows<br>
</p>
<p>00000000000002b8 R_BPF_64_64 network_flow_next_key<br>
</p>
<p>0000000000000318 R_BPF_64_64 network_flow_keys<br>
</p>
<p>0000000000000338 R_BPF_64_64 network_flows<br>
</p>
<p>0000000000000368 R_BPF_64_64 network_flow_keys<br>
</p>
<p>00000000000003b8 R_BPF_64_64 network_flows<br>
</p>
<p>00000000000003f0 R_BPF_64_64 network_flow_keys<br>
</p>
<p>0000000000000430 R_BPF_64_64 network_flows<br>
</p>
<p>00000000000008e8 R_BPF_64_64 network_flows<br>
</p>
<p>0000000000000928 R_BPF_64_64 network_flow_next_key<br>
</p>
<p>0000000000000980 R_BPF_64_64 network_flow_keys<br>
</p>
<p>00000000000009a0 R_BPF_64_64 network_flows<br>
</p>
<p>00000000000009d0 R_BPF_64_64 network_flow_keys<br>
</p>
<p>0000000000000a20 R_BPF_64_64 network_flows<br>
</p>
<p>0000000000000a58 R_BPF_64_64 network_flow_keys<br>
</p>
<p>0000000000000a90 R_BPF_64_64 network_flows<br>
</p>
<p>0000000000000af0 R_BPF_64_64 tcp_ip_scan_key<br>
&nbsp;</p>
<p>I see nothing about a string involving &quot;SYN&quot; or debug output there. These relocations are all just maps. It looks like the strings are indeed just directly inlined by the compiler. The few instances of strings being used that I've seen (mostly for bpf_trace_printk&nbsp;calls) are done the same way.</p>
<p>If we want to make use of strings for reversing, we'll need to do some byte searches to find them embedded in instruction immediates. This means we must be careful to search for sequences that won't be split up between instructions. In fact, even within an immediate, the bytes are split up.</p>
<p>We can see this by going to &quot;Options &gt; General,&quot; the &quot;Disassembly&quot; tab, and then setting &quot;Number of opcode bytes (non-graph)&quot; to 16 – the maximum width of an eBPF instruction. Cross-checking this against how&nbsp;llvm-objdump -dr&nbsp;displays the same block of code confirms the instruction bytes are displayed correctly, and that there are gaps of null bytes. Referencing the Linux kernel's built-in eBPF disassembler, the extra 64 bits in the lddw&nbsp;instruction are treated as another eBPF instruction where only the immediate field is used, so the other bits are left as zero.</p>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_1950852001.coreimg{.width}.png/1638465132835/ebpfkit-fig19.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig19.png" data-asset-id="59d5af2a-d393-4720-b565-6ed99f4041c2" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig19.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p><i>Figure 19 – Detail of 64-bit load eBPF instructions (lddw) used for string inlining</i></p>
<h3><b>Conclusion</b></h3>
<p>This obviously isn't a full reversing of ebpfkit, as much as it’s an overview of the process, and a demonstration that it's possible. A proper reversing job would continue by identifying where all the maps are referenced, determining if perf/ring buffers are used for output, and identifying where programs are attached.</p>
<p>From there we can determine a few other things such as: how these eBPF programs use maps to communicate to each other, how exactly these eBPF programs inspect data when they run, and if or how they attempt to modify data or behavior at all. We can quickly tell if something seems fishy, but it would take a bit more work to determine how exactly any malicious behavior is done. For example, whether files/processes are hidden, if data is leaked, what kind of communication channels exist, etc.</p>
<p>Visibility into compiled eBPF programs is going to become increasingly important, and until now the only options I'm aware of for reversing them have been unsatisfactory. ebpfkit poses an excellent example of this because it’s a very interesting and complex rootkit that heavily leverages eBPF for its functionality.</p>
<p>There's still a long way to go, but I think this is good progress for being able to reverse real-world eBPF programs. I've also tried to cover some of the peculiarities of eBPF programs that any reverser would need to know.</p>
<p>To conclude, here's some before-and-after screenshots of the&nbsp;kretprobe__64_sys_openat&nbsp;function in ebpfkit's main.o&nbsp;object. The first image is without the eBPF processor and just using the default MetaPC processor. The next is with our eBPF processor. The third image is with the eBPF processor and annotation script output.<br>
</p>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_613872150.coreimg{.width}.png/1638465132851/ebpfkit-fig20.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig20.png" data-asset-id="2a892f0b-80b9-43c0-9bed-37038d7f34e9" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig20.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <i>Figure 20 – Unsuccessful disassembly with an incorrect processor module<br>
&nbsp;</i>
    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_509189715.coreimg{.width}.png/1638465132867/ebpfkit-fig21.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig21.png" data-asset-id="e85b9abb-5ed3-4ec1-bd1f-7b3995abb1a1" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig21.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <i>Figure 21 – Successful disassembly with our eBPF processor module<br>
&nbsp;</i>
    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_496682506.coreimg{.width}.png/1638465132883/ebpfkit-fig22.png" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig22.png" data-asset-id="75c04377-1341-4b03-bfda-052c93e58863" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/12/ebpfkit-fig22.png" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="text">    
    
    <p><i>Figure 22 – Successful disassembly and annotations of helper calls, map references, and global references</i></p>
<h3><b>Future Work</b></h3>
<p>We may not continue working on this project, but we do have ideas of what directions this project can head in. We’ll leave this information here for any future users interested in improving the processor module.</p>
<p>Starting from this work, someone could build a proper IDA loader to provide better support for eBPF ELF files. This would need to handle their specific relocation types, and ideally the BTF information they may come with. This way we can get all the cross-references and annotations our scripts currently provide, but in a more robust way. This would allow for more robustly handling extern symbols. Even better, a dedicated section could be added for eBPF helpers as if they were also externs, so we could have cross-references for them instead of just comments.</p>
<p>The libbpf source would be a very detailed and informative reference for this, as it serves as a de-facto definition of how data in the ELF is interpreted for loading eBPF programs.</p>
<p>Additionally, it could be possible to use BTF information to add known structures or annotate accesses to a struct's fields, but I have not researched this at all.</p>
<p>Additionally, someone could build a separate loader and dumper to support analyzing programs loaded on a system. They would need to write a program that uses&nbsp;bpftool&nbsp;(and possibly libbpf or something similar) to dump loaded eBPF programs from a system, along with other necessary information like maps, and package that all up in a reasonable format. The accompanying loader would then use this bundle to load the programs into IDA, create map definitions, add cross-references, etc.</p>
<p>If a system is compromised by something like ebpfkit that actively tries to hide its tracks, and which will hide its maps and programs, this will be of no use. But it would still be useful for reversing more typical applications.</p>
<p>Tools like Volatility and their recent support for Linux's tracing framework would need to be used to sniff out rootkits on a compromised system, possibly alongside this eBPF processor module if eBPF code is encountered. But it's just as likely that the JITed version of a program would be available, with its own reversing quirks.</p>
<p>Though every instruction in the ELFs we've tested against is now recognized, not all instructions are handled by the processor. In the event that a binary uses an eBPF instruction that's currently unsupported, kernel source would need to be referenced to add support for analyzing and disassembling the instruction. Also, more work needs to be done on emulating the stack and defining variables to aid in analysis.</p>
<p>Finally, it would be wonderful to see similar work done for Ghidra, so this functionality can be available for more users. Hopefully this project can be a helpful reference for how to load, analyze, and disassemble an eBPF ELF file.<br>
</p>
<h3><b>Homework</b></h3>
<p>Here’s something you can do to give this project a test run if you’re interested in getting hands-on but don’t have any eBPF projects of your own. Try using this processor module and scripts to reverse some of the programs in this repository:&nbsp;<a href="https://github.com/pathtofile/bad-bpf" target="_blank">https://github.com/pathtofile/bad-bpf</a>. Everything should work fine, but it has not been tested, so if you run into any problems, please open an issue on the eBPF processor repo, with the sample eBPF ELF file that causes the problem.<br>
</p>
<h3><b>Reversing the Go Binary (Exercise for the Reader)</b></h3>
<p>ebpfkit builds to a Go binary with the eBPF ELF binaries embedded in it, to be updated and loaded at runtime. I haven't spent much time reversing this process to demonstrate precisely how to extract these from the binary, but here's some info to start with.</p>
<p>Examining source, we see that ebpfkit uses this package to pack the eBPF ELF files into the final binary:&nbsp;<a href="https://github.com/shuLhan/go-bindata/" target="_blank">https://github.com/shuLhan/go-bindata/</a>.</p>
<p>Using binwalk, we do indeed see that the beginnings of each gzipped ELF object reside in the&nbsp;.noptrdata&nbsp;section. However, this is only the beginning of the files, not the full files. We'll need to do more reversing and analysis to determine how exactly to pull this data out. But it's conceptually possible, there's no extra obfuscation of the objects, and the program itself is able to extract them.<br>
</p>
<h3><b>ebpfkit's Cilium-based Loading Alternative</b></h3>
<p>Another quirk of ebpfkit we didn’t directly deal with was its eBPF ELF loading process. Reading the source for ebpfkit, we note that it uses a fork of <a href="https://github.com/cilium/cilium" target="_blank">Cilium</a> for fixing up and loading eBPF programs, not libbpf. But it still uses Clang/LLVM to build the eBPF programs into ELF relocatable objects, and it parses these ELF objects in the loading process. So even projects that do not use libbpf should still have objects we can analyze if they use Clang/LLVM to build their eBPF programs.</p>
<p>The power of writing eBPF programs in C and building with Clang/LLVM is enough to make this a great choice for any complex eBPF project. Thus, it’s likely that any real-world need for eBPF reversing would involve eBPF ELF objects loadable by libbpf, regardless of whether libbpf is actually used.</p>
<h3><b>Thanks:</b></h3>
<p>I'd like to thank the rest of the Applied Research Team for all the help with eBPF internals, the IDA Pro API, and feedback on the tooling and writeup. I'd also like to thank&nbsp;Clément Berthaux, the original author of the plugin. Being able to start from existing work saved significant time and effort.</p>
<h3><b>References</b></h3>
<p>Here are some deeper references for eBPF and eBPF reversing:</p>
<ul>
<li><a href="https://github.com/zandi/eBPF_processor" target="_blank">https://github.com/zandi/eBPF_processor</a>&nbsp;- IDA eBPF processor and accompanying scripts. At time of writing, latest commit was&nbsp;c5295de3054f859f9a41c2f1a7ef61e895804908.</li>
<li><a href="https://github.com/iovisor/bpf-docs/blob/master/eBPF.md" target="_blank">https://github.com/iovisor/bpf-docs/blob/master/eBPF.md</a>&nbsp;- Quick reference for eBPF instruction format &amp; most common (but not all) instructions.</li>
<li><a href="https://elixir.bootlin.com/linux/v5.14.1/source/kernel/bpf/disasm.c" target="_blank">https://elixir.bootlin.com/linux/v5.14.1/source/kernel/bpf/disasm.c</a>&nbsp;- Linux kernel's eBPF disassembler, good reference for unsupported instructions, and to check our own disassembly against.</li>
<li><a href="https://github.com/llvm-mirror/llvm/blob/master/include/llvm/BinaryFormat/ELFRelocs/BPF.def" target="_blank">https://github.com/llvm-mirror/llvm/blob/master/include/llvm/BinaryFormat/ELFRelocs/BPF.def</a>&nbsp;- LLVM definition of eBPF ELF relocation types.<a href="https://github.com/cilium/ebpf/blob/54eeaaca78c67e2ebf01de27527fb77191c3b37b/elf_reader.go#L48" target="_blank">https://github.com/cilium/ebpf/blob/54eeaaca78c67e2ebf01de27527fb77191c3b37b/elf_reader.go#L48</a>&nbsp;- How the Cilium project loads their eBPF ELF files</li>
<li><a href="https://github.com/libbpf/libbpf" target="_blank">https://github.com/libbpf/libbpf</a>&nbsp;- Standalone source of libbpf. Very dense.</li>
</ul>
<p>Here are some eBPF programs to build and reverse:</p>
<ul>
<li><a href="https://github.com/Gui774ume/ebpfkit" target="_blank">https://github.com/Gui774ume/ebpfkit</a>&nbsp;- eBPF powered rootkit examined in this post, at commit&nbsp;387dba934ac9ad6d5b4a57315e3d6acb9cfecfc2.</li>
<li><a href="https://github.com/pathtofile/bad-bpf" target="_blank">https://github.com/pathtofile/bad-bpf</a>&nbsp;- Another collection of malicious eBPF programs.</li>
<li><a href="https://github.com/vbpf/ebpf-samples" target="_blank">https://github.com/vbpf/ebpf-samples</a>&nbsp;- Prebuilt which is nice, and it also contains some older ELFs. Good for making sure we support a variety of valid eBPF ELF files.</li>
</ul>
<p>These are a bit more general and intro-friendly:</p>
<ul>
<li><a href="https://github.com/libbpf/libbpf-bootstrap" target="_blank">https://github.com/libbpf/libbpf-bootstrap</a>&nbsp;- Bootstrap to easily get started writing eBPF programs with libbpf.</li>
<li><a href="https://github.com/iovisor/bpftrace" target="_blank">https://github.com/iovisor/bpftrace</a>&nbsp;- bpftrace tool and tool collection, great for easily seeing what eBPF can do. Lots of very useful tools.</li>
<li><a href="https://ebpf.io/" target="_blank">https://ebpf.io/</a>&nbsp;- Overall good starting point for learning about eBPF.<br>
&nbsp;</li>
</ul>

    
    
</div>


    
    
    <div class="image">
  <div data-cmp-is="image" data-cmp-src="/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool/_jcr_content/main/par/sectionblog/par/image_1628465033.coreimg{.width}.jpeg/1638465132899/cobalt-strike-beacon-1200px-banner.jpeg" data-asset="/content/dam/blogs-blackberry-com/images/blogs/2021/10/cobalt-strike-beacon-1200px-banner.jpg" data-asset-id="2dbf649e-e931-4f8a-9ae8-c265a164265b" class="cmp-image" itemscope itemtype="http://schema.org/ImageObject">
 
     
         
         <!--/*Figure and figcaption elements added by Zahid*/>-->
          
         <img src="/content/dam/blogs-blackberry-com/images/blogs/2021/10/cobalt-strike-beacon-1200px-banner.jpg" class="cmp-image__image" itemprop="contentUrl" data-cmp-hook-image="image" alt/>
         
         <figcaption class="figure-caption" styles="display:table-caption;caption-side:bottom;"></figcaption>
          
     
 
 
 
</div>

    
</div>


    
    
    <div class="authorblog"><!--Pulling author bio from author page-->

    
    
        
  



<div class="author-info" data-author-name="Michael Zandi" data-author-path="https://blogs.blackberry.com/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool">
  <div class="author-avatar">
    
    <img src="/content/dam/blogs-blackberry-com/images/blogs/logos/blackberry-logo-140x140.jpg" class="author-avatar" alt="Michael Zandi"/>				
    
  </div><!-- .author-avatar -->
  <div class="author-description">
      
    
    <h2>About Michael Zandi</h2>
    <p class="author-position"><b>Software Engineer Associate of Applied Research at BlackBerry.<br />
 </b></p>

  </div><!-- .author-description	-->
</div>
<hr class="author-hr"/>
    
        
  



<div class="author-info" data-author-name="The BlackBerry Research &amp; Intelligence Team" data-author-path="https://blogs.blackberry.com/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool">
  <div class="author-avatar">
    
    <img src="/content/dam/blogs-blackberry-com/images/authors/blackberry-logo-square.jpg" class="author-avatar" alt="The BlackBerry Research &amp; Intelligence Team"/>				
    
  </div><!-- .author-avatar -->
  <div class="author-description">
      
    
    <h2>About The BlackBerry Research &amp; Intelligence Team</h2>
    <p>The BlackBerry Research &amp; Intelligence team examines emerging and persistent threats, providing intelligence analysis for the benefit of defenders and the organizations they serve.</p>

  </div><!-- .author-description	-->
</div>
<hr class="author-hr"/>
    
</div>


    
    
    <div class="socialsharing">

<div class='socialSharing row'>
  <ul class='socialSharing-icons'>
    <li>
        <a href='https://twitter.com/intent/tweet?url=https://blogs.blackberry.com/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool&text=Reverse%20Engineering%20Ebpfkit%20Rootkit%20With%20BlackBerry%27s%20Enhanced%20IDA%20Processor%20Tool&via=BlackBerry' title="Share on Twitter" target="_blank" class="twitter-share">
        <span class='sr-only sr-only-focusable'>Share on Twitter</span>
        <span class='svgIcon-socialSharing svgIcon-socialSharing--tw' aria-hidden='true'>
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
        </span>
      </a>
    </li>    
    <li>
      <a href='https://www.facebook.com/sharer/sharer.php?u=https://blogs.blackberry.com/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool' title="Share on FaceBook" target="_blank" class="facebook-share">
        <span class='sr-only sr-only-focusable'>Share on Facebook</span>
        <span class='svgIcon-socialSharing svgIcon-socialSharing--fb' aria-hidden='true'>
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 264 512"><path d="M76.7 512V283H0v-91h76.7v-71.7C76.7 42.4 124.3 0 193.8 0c33.3 0 61.9 2.5 70.2 3.6V85h-48.2c-37.8 0-45.1 18-45.1 44.3V192H256l-11.7 91h-73.6v229"/></svg>
        </span>
      </a>
    </li>
    <li>
      <a href="https://www.linkedin.com/shareArticle?mini=true&url=https://blogs.blackberry.com/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool&title=Reverse%20Engineering%20Ebpfkit%20Rootkit%20With%20BlackBerry%27s%20Enhanced%20IDA%20Processor%20Tool&summary=&source=blogs.blackberry.com" title="Share on LinkedIn" target="_blank" class="linkedin-share">
        <span class='sr-only sr-only-focusable'>Share on Linked In</span>
        <span class='svgIcon-socialSharing svgIcon-socialSharing--li' aria-hidden='true'>
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448.1 512"><path d="M100.3 448H7.4V148.9h92.9V448zM53.8 108.1C24.1 108.1 0 83.5 0 53.8S24.1 0 53.8 0s53.8 24.1 53.8 53.8-24.1 54.3-53.8 54.3zM448 448h-92.7V302.4c0-34.7-.7-79.2-48.3-79.2-48.3 0-55.7 37.7-55.7 76.7V448h-92.8V148.9h89.1v40.8h1.3c12.4-23.5 42.7-48.3 87.9-48.3 94 0 111.3 61.9 111.3 142.3V448h-.1z"/></svg>
        </span>
      </a>
    </li>
    <li>
      <a href="mailto:?subject=Reverse%20Engineering%20Ebpfkit%20Rootkit%20With%20BlackBerry%27s%20Enhanced%20IDA%20Processor%20Tool&body=https://blogs.blackberry.com/en/2021/12/reverse-engineering-ebpfkit-rootkit-with-blackberrys-free-ida-processor-tool" title="Email" class="email-share">
        <span class='sr-only sr-only-focusable'>Email</span>
        <span class='svgIcon-socialSharing svgIcon-socialSharing--li' aria-hidden='true'>
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z"/></svg>
        </span>
      </a>
    </li>    
  </ul>
</div>
</div>


    
    
    <div class="backbutton">
<a href="javascript:history.back()" class="cta cta-primary btn-back-button">Back</a></div>



      </div>
      
          
      </div>
    </section>
      
  
  
</div>



</main>

<!-- BEGIN DO NOT INDEX -->
<footer>
    <div class="container pt-2">
    <nav id='footerNav'>
        <div>
            <div class="row my-4">
                <div class='socialLinks col-lg-4 col-md-4 col-sm-12 pb-3'>
                    <a href='https://www.facebook.com/BlackBerry/' class='socialLink px-3 pl-0' target="_blank" rel="noopener" style="padding-left:0 !important;">
                      <span class='sr-only' aria-label="BlackBerry Facebook Account">Facebook</span>
                      <span class='svgIcon-social fb' aria-hidden="true">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M448 56.7v398.5c0 13.7-11.1 24.7-24.7 24.7H309.1V306.5h58.2l8.7-67.6h-67v-43.2c0-19.6 5.4-32.9 33.5-32.9h35.8v-60.5c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87 89.4v49.9h-58.4v67.6h58.4V480H24.7C11.1 480 0 468.9 0 455.3V56.7C0 43.1 11.1 32 24.7 32h398.5c13.7 0 24.8 11.1 24.8 24.7z"/>
                        </svg>
                      </span>
                    </a>
                    <a href='https://twitter.com/blackberry' target="_blank" class='socialLink px-3 ' rel="noopener">
                      <span class='sr-only' aria-label="BlackBerry Twitter Account">Twitter</span>
                      <span class='svgIcon-social tw'>
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
                      </span>
                    </a>
                    <a href='https://www.youtube.com/user/BlackBerry' target="_blank" class='socialLink px-3' rel="noopener">
                      <span class='sr-only' aria-label="BlackBerry YouTube Account">YouTube</span>
                      <span class='svgIcon-social yt'>
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"/></svg>
                      </span>                      
                    </a>
                    <a href='https://www.instagram.com/blackberry/' target="_blank" class='socialLink youTube px-3' rel="noopener">
                      <span class='sr-only' aria-label="BlackBerry Instagram Account">Instagram</span>
                      <span class='svgIcon-social ig'>
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"/></svg>
                      </span>                        
                    </a>
                                 
                  </div>
                
<!--                  <div class="col-lg-4  col-md-4 col-sm-12 pb-3" data-sly-test="true">-->
<!--                    <a href="https://www.blackberry.com/us/en/forms/enterprise/contact-us" target="_blank" style="color:black; font-size: 16px;">Contact Us</a>-->
<!--                  </div>-->
<!--                <div class="col-lg-4  col-md-4 col-sm-12 pb-3" data-sly-test="false">-->
<!--                    <a href="https://www.blackberry.com/ja/jp/forms/enterprise/contact-us" target="_blank" style="color:black; font-size: 16px;">Contact Us</a>-->
<!--                </div>-->
<!--                  <div class="col-lg-4  col-md-4 col-sm-12 pb-3" data-sly-test="true">-->
<!--                    <a href="https://www.blackberry.com/us/en/support" target="_blank" style="color: black; font-size: 16px;">Support</a>-->
<!--                  </div>-->
<!--                <div class="col-lg-4  col-md-4 col-sm-12 pb-3" data-sly-test="false">-->
<!--                    <a href="https://www.blackberry.com/ja/jp/support/overview" target="_blank" style="color: black; font-size: 16px;">Support</a>-->
<!--                </div>-->
            </div>
            <hr/>
            <div class='row mt-5'>
               <!--/% <div class='col-xs-12 col-md-3'>
                   
                    <sly data-sly-list.col1="">
                        
                          <a class="footerCollapse" role="button" data-toggle="collapse" href="#collapse1" aria-expanded="false" aria-controls="collapse1">
                          	<h3>
                              <span class='open'>
                                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"/></svg>
                              </span>
                              <span class='closed'>
                                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z"/></svg>
                              </span> 
                            </h3>
                          </a>
                          
                        <sly data-sly-list.children="">
                        	<div class="collapse in" id="collapse1">
                            <ul data-sly-list.leveltwo="">
                                <li>
                                    <sly data-sly-use.navLink="Footer">
                                        <sly data-sly-test="">
                                            <a href="" data-sly-attribute.target=""></a>
                                        </sly>
                                        <sly data-sly-test="true">
                                            <a href="" data-sly-attribute.target="" rel="noopener"></a>
                                        </sly>
                                    </sly>
                                </li>
                            </ul>
                            </div>
                        </sly>
                    </sly>
                </div>
%/-->
                <div class='col-xs-12 col-md-4'>
                    <!--Col-2-->
                    
                        <a class="footerCollapse" role="button" data-toggle="collapse" href="#collapse21" aria-expanded="false" aria-controls="collapse21">
                        	<h3>Corporate
                              <span class='open'>
                                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"/></svg>
                              </span>
                              <span class='closed'>
                                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z"/></svg>
                              </span>
                            </h3>
                        </a>
                        
                        	<div class="collapse in" id="collapse21">
                            <ul>
                                <li>
                                    
                                        
                                        
                                            <a href="https://www.blackberry.com/us/en/company" rel="noopener" target="_blank">Company</a>
                                        
                                    
                                </li>
                            
                                <li>
                                    
                                        
                                            <a href="https://www.blackberry.com/us/en/company/newsroom" target="_blank">Newsroom</a>
                                        
                                        
                                    
                                </li>
                            
                                <li>
                                    
                                        
                                            <a href="https://www.blackberry.com/us/en/company/investors" target="_blank">Investors</a>
                                        
                                        
                                    
                                </li>
                            
                                <li>
                                    
                                        
                                        
                                            <a href="https://www.blackberry.com/us/en/company/careers" rel="noopener" target="_blank">Careers</a>
                                        
                                    
                                </li>
                            
                                <li>
                                    
                                        
                                            <a href="https://www.blackberry.com/us/en/company/leadership" target="_blank">Leadership</a>
                                        
                                        
                                    
                                </li>
                            
                                <li>
                                    
                                        
                                            <a href="https://www.blackberry.com/us/en/company/corporate-responsibility-at-blackberry" target="_blank">Corporate Responsibility</a>
                                        
                                        
                                    
                                </li>
                            
                                <li>
                                    
                                        
                                        
                                            <a href="https://www.blackberry.com/us/en/company/certifications" rel="noopener" target="_blank">Certifications</a>
                                        
                                    
                                </li>
                            
                                <li>
                                    
                                        
                                        
                                            <a href="https://www.blackberry.com/us/en/success-stories" rel="noopener" target="_blank">Customer Success</a>
                                        
                                    
                                </li>
                            </ul>
                            </div>
                        
                    
                </div>

                <div class='col-xs-12 col-md-4'>
                    <!--Col-3-->
                    
                    	<a class="footerCollapse" role="button" data-toggle="collapse" href="#collapse31" aria-expanded="false" aria-controls="collapse31">
                        	<h3>Developers
                              <span class='open'>
                                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"/></svg>
                              </span>
                              <span class='closed'>
                                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z"/></svg>
                              </span>
                            </h3>
                        </a>
                        
                        	<div class="collapse in" id="collapse31">
                            <ul>
                                <li>
                                    
                                        
                                        
                                            <a href="https://developers.blackberry.com/" rel="noopener" target="_blank">Enterprise Platform &amp; Apps</a>
                                        
                                    
                                </li>
                            
                                <li>
                                    
                                        
                                        
                                            <a href="https://www.qnx.com/account/login.html?returnaddress=%2Fdownload%2Fgroup.html%3Fprogramid%3D29178" rel="noopener" target="_blank">BlackBerry QNX Developer Network</a>
                                        
                                    
                                </li>
                            </ul>
                            </div>
                        
                    
                    	<a class="footerCollapse" role="button" data-toggle="collapse" href="#collapse32" aria-expanded="false" aria-controls="collapse32">
                        	<h3>Blogs
                              <span class='open'>
                                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"/></svg>
                              </span>
                              <span class='closed'>
                                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z"/></svg>
                              </span>
                            </h3>
                        </a>
                        
                        	<div class="collapse in" id="collapse32">
                            <ul>
                                <li>
                                    
                                        
                                        
                                            <a href="https://blogs.blackberry.com/" rel="noopener">BlackBerry ThreatVector Blog</a>
                                        
                                    
                                </li>
                            
                                <li>
                                    
                                        
                                        
                                            <a href="https://devblog.blackberry.com/" rel="noopener" target="_blank">Developers Blog</a>
                                        
                                    
                                </li>
                            
                                <li>
                                    
                                        
                                        
                                            <a href="https://helpblog.blackberry.com/" rel="noopener" target="_blank">Help Blog</a>
                                        
                                    
                                </li>
                            </ul>
                            </div>
                        
                    
                </div>

                <div class='col-xs-12 col-md-4'>
                    <!--Col-4-->
                    
                        <a class="footerCollapse" role="button" data-toggle="collapse" href="#collapse41" aria-expanded="false" aria-controls="collapse41">
                        	<h3>Legal
                              <span class='open'>
                                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"/></svg>
                              </span>
                              <span class='closed'>
                                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z"/></svg>
                              </span>
                            </h3>
                        </a>
                        
                        	<div class="collapse in" id="collapse41">
                            <ul>
                                <li>
                                    
                                        
                                            <a href="https://www.blackberry.com/us/en/legal" target="_blank">Overview</a>
                                        
                                        
                                    
                                </li>
                            
                                <li>
                                    
                                        
                                            <a href="https://www.blackberry.com/us/en/legal/accessibility" target="_blank">Accessibility</a>
                                        
                                        
                                    
                                </li>
                            
                                <li>
                                    
                                        
                                            <a href="https://www.blackberry.com/us/en/legal/blackberry-virtual-patent-marking" target="_blank">Patents</a>
                                        
                                        
                                    
                                </li>
                            
                                <li>
                                    
                                        
                                            <a href="https://www.blackberry.com/us/en/legal/trademarks" target="_blank">Trademarks</a>
                                        
                                        
                                    
                                </li>
                            
                                <li>
                                    
                                        
                                            <a href="https://www.blackberry.com/us/en/legal/privacy-policy" target="_blank">Privacy Policy</a>
                                        
                                        
                                    
                                </li>
                            </ul>
                            </div>
                        
                    
            </div>
            </div>
        </div>
        <div class='container'>
            <div class='row tm10' style="padding-top: 50px">
                <div class='col-xs-12 col-md-6 copyright' copyright>
                    <p>
                        © 2020 BlackBerry Limited. All rights reserved.
                    </p>
                </div>
              
                
            </div>
        </div>

    </nav>
    </div>
</footer>
<!-- END DO NOT INDEX -->
            
    
    
    
    
<script src="/etc.clientlibs/shared/clientlibs/jquery.min.js"></script>
<script src="/etc.clientlibs/qnxv2/clientlibs/shared/clientlibs/jquery.min.js"></script>
<script src="/etc.clientlibs/blogs-bbcom/clientlibs/clientlib-dependencies.min.js"></script>





    
    
<script src="/etc.clientlibs/blogs-bbcom/clientlibs/clientlib-site.min.js"></script>




    

    

    

            

            <!-- Cookie compliance -->
<div id="cookieNotice" role="region" aria-label="Cookie Consent Agreement" class="cookieNotice container animated" style="height: auto; display: none">

  <div class="noticeWrapper row col-lg-8 col-md-8 col-sm-12 mx-auto">
    <a role="button" id="close">
      <img alt="Close Button" src="/content/dam/blackberry-com/Images/icons/close.png"/>
    </a>
    <p class="col-lg-12 col-md-12 col-sm-12">
        BlackBerry uses cookies to help make our website better. Some of the cookies are necessary for proper
            functioning of the site, while others are to help us understand how you use it. <a title="BlackBerry Privacy Policy" href="https://www.blackberry.com/us/en/legal/privacy-policy">Read more here</a> about our cookies, and how you can
            opt out. By continuing to use this site you accept our use of cookies.
    </p>
  </div>
</div>
<script>
  $(document).ready(function () {
    var cookieNotice = $("#cookieNotice");
    var left = parseInt($(window).width()) / 2 - ((parseInt(cookieNotice.width()) / 2) + 31);

    if ($(window).width() > 768) {
      cookieNotice.css({ 'left': (left + 'px') });
    }


    function openConsent() {
      cookieNotice.addClass("slideInUp");
      cookieNotice.css('display', 'block');
    }

    function closeConsent() {
      cookieNotice.removeClass("slideInUp");
      cookieNotice.removeClass("animated");
      cookieNotice.addClass("fadeOut animated");
      cookieNotice.css('display', 'none');
    }

    $("#close").click(function () {
      closeConsent();
      var d = new Date();
      d.setTime(d.getTime() + (365 * 24 * 60 * 60 * 1000)); //1 year
      var expires = "expires=" + d.toUTCString();
      //var expires = window.navigator.userAgent.indexOf('MSIE') == -1 ? ' expires=0;' : ''; //Session
      if (navigator.userAgent.indexOf("Chrome") != -1) {
        document.cookie = 'cookieConsentClosed' + '=true;' + expires + ';path=/';
      }
      else {
        document.cookie = 'cookieConsentClosed' + '=true;' + expires + ';path=/;domain=.blackberry.com';
      }

    });

    var x = document.cookie;
    if (!(x.indexOf("cookieConsentClosed=true") > -1)) {
      setTimeout(function () {
        openConsent();
      }, 2000);

    }
  });

</script>
<style>
  .noticeWrapper {
    padding-top: 21px;
    font-size: 13px;
    text-align: center;
    background-color: white;
    border-right: 1px solid black;
    border-top: 1px solid black;
    border-left: 1px solid black;
    border-radius: 8px 8px 0px 0px;
    -moz-border-radius: 8px 8px 0px 0px;
    -webkit-border-radius: 8px 8px 0px 0px;
  }

  .cookieNotice p {
    font-size: 13px;
    line-height: 1.5;
    text-align: initial;
    margin-bottom: 21px;
  }

  .cookieNotice p a { 
    font-size: 13px;
    line-height: 1.5;
    text-align: initial;
  }

  .cookieNotice p a:hover {
    text-decoration: underline !important;
  }

  #close {
    position: absolute;

    top: -10px;
    right: -10px;
  }

  @media only screen and (max-width: 768px) {
    #close {
      border-radius: 0;

      top: -10px;
      right: -10px;
    }
  }

  .cookieNotice {
    height: 0px;

    position: fixed;
    z-index: 1000;
    bottom: 0;

    background-color: transparent;
    overflow: visible;
    transition: 0.5s;



    color: #000 !important;

    border: 0px solid #000000;

  }

  @media only screen and (max-width: 768px) {
    .cookieNotice {
      width: 100%;
      border-radius: 0px;
      -moz-border-radius: 0px;
      -webkit-border-radius: 0px;
    }
  }


  #page-content {
    transition: margin-bottom .5s;
    padding: 16px;
  }
</style>
            
            <script>

  (function () {

    var getParameterByName = function (name, url) {
      if (!url) url = window.location.href;
      name = name.replace(/[\[\]]/g, '\\$&');
      var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
        results = regex.exec(url);
      if (!results) return null;
      if (!results[2]) return '';
      return decodeURIComponent(results[2].replace(/\+/g, ' '));
    }
    var getParentAnchor = function (element) {

      while (element !== null && !(element instanceof HTMLDocument)) {
        if (element.tagName.toUpperCase() === "A") {
          return element;
        }
        element = element.parentNode;
      }
      return null;
    };

    if (document.title === '404') {
      _satellite.track("error",
        { "errorType": "404", "pageURL": document.location.href }
      );

    }

    document.addEventListener('click', function (event) {
      var downloadFiles = [".pdf", ".exe", ".zip",".gzip",".gz",".tar",".jar",".bin",".dmg",".tgz",".mp4"];
      var videoSourceFound = "";
      var elem = getParentAnchor(event.target)
      if (elem !== null) {
        var urlSplit = elem.href.split("/");
        if (elem.matches("a.twitter-share") || elem.matches("a.facebook-share") || elem.matches("a.linkedin-share") || elem.matches("a.email-share")) {
          _satellite.track("social_share",
            { "socialName": elem.className.split('-')[0] }
          );
        }
        else if (elem.hasAttribute("data-lity")) {
          var videoSources = { scene7: "s7d2.scene7.com", youtube: ["youtu.be", "youtube.com"], vimeo: "vimeo.com" };
          for (var key in videoSources) {
            if (videoSources.hasOwnProperty(key)) {
              if (Array.isArray(videoSources[key])) {
                videoSources[key].forEach(function (domain, i) {
                  if (elem.href.indexOf(domain) > -1) {
                    videoSourceFound = key;
                  }
                });

              } else {
                if (elem.href.indexOf(videoSources[key]) > -1) {
                  videoSourceFound = key;
                }
              }
            }
          }
          if (videoSourceFound !== "") {
            var linkHref = videoSourceFound === "scene7" ? getParameterByName("asset",elem.href): elem.href;
            _satellite.track("video", {
              "linkHref": linkHref,
              "videoPlatform": videoSourceFound,
              "linkText": elem.text.trim()
            });
          }

        }
        else if (elem.text.toLowerCase().indexOf("subscribe") > -1 || elem.text.toLowerCase().indexOf("register for updates") > -1) {
          _satellite.track("subscribe",
            { "linkText": elem.text.trim() }
          );
        }
        else if (elem.text.toLowerCase().indexOf("contact us") > -1 || elem.text.toLowerCase().indexOf("contact sales") > -1) {
          _satellite.track("contact_us",
            { "linkText": elem.text.trim() }
          );
        }
        else if (!(elem.host.indexOf(window.location.host) > -1) && elem.href !== "" && videoSourceFound == "") {
          _satellite.track("site_exit", {
            "site": elem.hostname
          });
        }

        for (var i = 0; i < downloadFiles.length; i++) {
          if (elem.href.toLowerCase().indexOf(downloadFiles[i]) > -1) {
            var fileName = urlSplit[urlSplit.length - 1];
            _satellite.track("download",
              { "fileName": fileName }
            );
          }
        }
      }
    }, false);


  })();


</script>



<script>
    function getGclidQueryParameter(p) {
      var match = RegExp('[?&]' + p + '=([^&]*)').exec(window.location.search);
      return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
    }

    function getExpiryRecord(value) {
      var expiryPeriod = 90 * 24 * 60 * 60 * 1000; // 90 day expiry in milliseconds

      var expiryDate = new Date().getTime() + expiryPeriod;
      return {
        value: value,
        expiryDate: expiryDate
      };
    }

    function addGclid() {
      var gclidParam = getGclidQueryParameter('gclid');
      var gclidFormFields = ['gclid_field']; // all possible gclid form field ids here
      var gclidRecord = null;
      var currGclidFormField;

      var gclsrcParam = getGclidQueryParameter('gclsrc');
      var isGclsrcValid = !gclsrcParam || gclsrcParam.indexOf('aw') !== -1;

      gclidFormFields.forEach(function (field) {
        if (document.getElementById(field)) {
          currGclidFormField = document.getElementById(field);
        }
      });

      if (gclidParam && isGclsrcValid) {
        gclidRecord = getExpiryRecord(gclidParam);
        localStorage.setItem('gclid', JSON.stringify(gclidRecord));
      }

      var gclid = gclidRecord || JSON.parse(localStorage.getItem('gclid'));
      var isGclidValid = gclid && new Date().getTime() < gclid.expiryDate;

      if (currGclidFormField && isGclidValid) {
        currGclidFormField.value = gclid.value;
      }
    }

    window.addEventListener('load', addGclid);
  </script>
        
    </body>
</html>
